package mini.expr;
import java.util.List;
import java.util.LinkedList;

import mini.ExpressionList;
import mini.Env;
import mini.Proc;
import mini.util.MiniUtil;


//added for 2c
public class FunctionCall extends Expr {

    private String funcid = null;	// If it's a symbolic reference
    private ExpressionList explist;
    private Proc proc = null;	// If it's a literal reference

    public FunctionCall(String id, ExpressionList el) {
        funcid = id;
        explist = el;
    }

    public FunctionCall(Proc proc, ExpressionList el) {
        this.proc = proc;
        funcid = "lambda";
        explist = el;
    }

    public Element eval(List<Env> listOfEnvs, LinkedList var) {

    	// Assume we've set the proc literally
    	Proc procToCall = proc;
    	
    	// But look for it symbolically if we haven't
    	if( procToCall == null ) {
        	// It might be the name of a function itself
        	procToCall = MiniUtil.lookupFunction(listOfEnvs,funcid);
        	
        	// Or, it could be an element that points to a function
        	if( procToCall == null ) {
        		Element elem = MiniUtil.lookupSymbol(listOfEnvs, funcid);
        		procToCall = elem.getProcValue();
        	}
    	}
    	
        return procToCall.apply(listOfEnvs, var, explist);
    }
}